#ifdef SQPLUS_DECLARE_INSTANCE_TYPE_CONST
#undef SQPLUS_DECLARE_INSTANCE_TYPE_CONST

#ifdef SQPLUS_SUPPORT_NULL_INSTANCES

#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \
  DECLARE_INSTANCE_TYPE_NAME_T(TYPE,NAME) \
  namespace SqPlus { \
    inline void Push( HSQUIRRELVM v, const TYPE * value ) { \
      if( !value ) { \
        sq_pushnull( v ); \
      } else if( !CreateNativeClassInstance( v, GetTypeName( *value ), ( TYPE* )value, 0 ) ) { \
        throw SquirrelError( sqT( "无法创建实例指针（检查注册名）" ) ); \
      } \
    } \
    inline void Push( HSQUIRRELVM v, const TYPE & value ) { \
      if( !CreateCopyInstance( GetTypeName( value ), value ) ) { \
        throw SquirrelError( sqT( "无法创建实例指针副本（检查注册名）" ) ); \
      } \
    } \
    inline bool Match( TypeWrapper<const TYPE &>, HSQUIRRELVM v, int idx ) { \
      return  GetInstance<TYPE, false>( v, idx ) != NULL; \
    } \
    inline const TYPE & Get( TypeWrapper<const TYPE &>, HSQUIRRELVM v, int idx ) { \
      return *GetInstance<TYPE, true>( v, idx ); \
    } \
  }
#else

#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \
  DECLARE_INSTANCE_TYPE_NAME_T(TYPE,NAME) \
  namespace SqPlus { \
    inline void Push( HSQUIRRELVM v, const TYPE * value ) { \
      if( !CreateNativeClassInstance( v, GetTypeName( *value ), ( TYPE* )value, 0 ) ) { \
        throw SquirrelError( sqT( "无法创建实例指针（检查注册名）" ) ); \
      } \
    } \
    inline void Push( HSQUIRRELVM, const TYPE & value ) { \
      if( !CreateCopyInstance( GetTypeName( value ), value ) ) { \
        throw SquirrelError( sqT( "无法创建实例指针副本（检查注册名）" ) ); \
      } \
    } \
    inline bool Match( TypeWrapper<const TYPE &>, HSQUIRRELVM v, int idx ) { \
      return GetInstance<TYPE, false>( v, idx ) != NULL; \
    } \
    inline const TYPE & Get( TypeWrapper<const TYPE &>, HSQUIRRELVM v, int idx ) { \
      return *GetInstance<TYPE, true>( v, idx ); \
    } \
  }
#endif

#define DECLARE_INSTANCE_TYPE(TYPE) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,TYPE)
#define DECLARE_INSTANCE_TYPE_NAME(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME)
#endif

#ifdef SQPLUS_CALL_CONST_MFUNC_RET0
#undef SQPLUS_CALL_CONST_MFUNC_RET0
template <typename Callee>
static int Call( Callee & callee, RT( Callee::*func )() const, HSQUIRRELVM v, int ) {
  RT ret = ( callee.*func )();
  Push( v, ret );
  return 1;
}

#ifdef _WIN64
template <typename Callee>
static int Call( Callee & callee, RT( Callee::*func )() const, HSQUIRRELVM v, SQInteger ) {
  RT ret = ( callee.*func )();
  Push( v, ret );
  return 1;
}
#endif

template <typename Callee, typename P1>
static int Call( Callee & callee, RT( Callee::*func )( P1 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  RT ret = ( callee.*func )(
             Get( TypeWrapper<P1>(), v, index + 0 )
           );
  Push( v, ret );
  return 1;
}

template<typename Callee, typename P1, typename P2>
static int Call( Callee & callee, RT( Callee::*func )( P1, P2 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  RT ret = ( callee.*func )(
             Get( TypeWrapper<P1>(), v, index + 0 ),
             Get( TypeWrapper<P2>(), v, index + 1 )
           );
  Push( v, ret );
  return 1;
}

template<typename Callee, typename P1, typename P2, typename P3>
static int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  RT ret = ( callee.*func )(
             Get( TypeWrapper<P1>(), v, index + 0 ),
             Get( TypeWrapper<P2>(), v, index + 1 ),
             Get( TypeWrapper<P3>(), v, index + 2 )
           );
  Push( v, ret );
  return 1;
}

template<typename Callee, typename P1, typename P2, typename P3, typename P4>
static int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3, P4 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  sq_argassert( 4, index + 3 );
  RT ret = ( callee.*func )(
             Get( TypeWrapper<P1>(), v, index + 0 ),
             Get( TypeWrapper<P2>(), v, index + 1 ),
             Get( TypeWrapper<P3>(), v, index + 2 ),
             Get( TypeWrapper<P4>(), v, index + 3 )
           );
  Push( v, ret );
  return 1;
}

template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5>
static int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3, P4, P5 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  sq_argassert( 4, index + 3 );
  sq_argassert( 5, index + 4 );
  RT ret = ( callee.*func )(
             Get( TypeWrapper<P1>(), v, index + 0 ),
             Get( TypeWrapper<P2>(), v, index + 1 ),
             Get( TypeWrapper<P3>(), v, index + 2 ),
             Get( TypeWrapper<P4>(), v, index + 3 ),
             Get( TypeWrapper<P5>(), v, index + 4 )
           );
  Push( v, ret );
  return 1;
}

template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
static int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3, P4, P5, P6 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  sq_argassert( 4, index + 3 );
  sq_argassert( 5, index + 4 );
  sq_argassert( 6, index + 5 );
  RT ret = ( callee.*func )(
             Get( TypeWrapper<P1>(), v, index + 0 ),
             Get( TypeWrapper<P2>(), v, index + 1 ),
             Get( TypeWrapper<P3>(), v, index + 2 ),
             Get( TypeWrapper<P4>(), v, index + 3 ),
             Get( TypeWrapper<P5>(), v, index + 4 ),
             Get( TypeWrapper<P6>(), v, index + 5 )
           );
  Push( v, ret );
  return 1;
}

template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
static int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3, P4, P5, P6, P7 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  sq_argassert( 4, index + 3 );
  sq_argassert( 5, index + 4 );
  sq_argassert( 6, index + 5 );
  sq_argassert( 7, index + 6 );
  RT ret = ( callee.*func )(
             Get( TypeWrapper<P1>(), v, index + 0 ),
             Get( TypeWrapper<P2>(), v, index + 1 ),
             Get( TypeWrapper<P3>(), v, index + 2 ),
             Get( TypeWrapper<P4>(), v, index + 3 ),
             Get( TypeWrapper<P5>(), v, index + 4 ),
             Get( TypeWrapper<P6>(), v, index + 5 ),
             Get( TypeWrapper<P7>(), v, index + 6 )
           );
  Push( v, ret );
  return 1;
}
#endif

#ifdef SQPLUS_CALL_CONST_MFUNC_NORET
#undef SQPLUS_CALL_CONST_MFUNC_NORET
template<typename Callee>
static int Call( Callee & callee, void ( Callee::*func )() const, HSQUIRRELVM, int ) {
  ( callee.*func )();
  return 0;
}

template<typename Callee, typename P1>
static int Call( Callee & callee, void ( Callee::*func )( P1 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  ( callee.*func )(
    Get( TypeWrapper<P1>(), v, index + 0 )
  );
  return 0;
}

template<typename Callee, typename P1, typename P2>
static int Call( Callee & callee, void ( Callee::*func )( P1, P2 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  ( callee.*func )(
    Get( TypeWrapper<P1>(), v, index + 0 ),
    Get( TypeWrapper<P2>(), v, index + 1 )
  );
  return 0;
}

template<typename Callee, typename P1, typename P2, typename P3>
static int Call( Callee & callee, void ( Callee::*func )( P1, P2, P3 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  ( callee.*func )(
    Get( TypeWrapper<P1>(), v, index + 0 ),
    Get( TypeWrapper<P2>(), v, index + 1 ),
    Get( TypeWrapper<P3>(), v, index + 2 )
  );
  return 0;
}

template<typename Callee, typename P1, typename P2, typename P3, typename P4>
static int Call( Callee & callee, void ( Callee::*func )( P1, P2, P3, P4 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  sq_argassert( 4, index + 3 );
  ( callee.*func )(
    Get( TypeWrapper<P1>(), v, index + 0 ),
    Get( TypeWrapper<P2>(), v, index + 1 ),
    Get( TypeWrapper<P3>(), v, index + 2 ),
    Get( TypeWrapper<P4>(), v, index + 3 )
  );
  return 0;
}

template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5>
static int Call( Callee & callee, void ( Callee::*func )( P1, P2, P3, P4, P5 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  sq_argassert( 4, index + 3 );
  sq_argassert( 5, index + 4 );
  ( callee.*func )(
    Get( TypeWrapper<P1>(), v, index + 0 ),
    Get( TypeWrapper<P2>(), v, index + 1 ),
    Get( TypeWrapper<P3>(), v, index + 2 ),
    Get( TypeWrapper<P4>(), v, index + 3 ),
    Get( TypeWrapper<P5>(), v, index + 4 )
  );
  return 0;
}

template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
static int Call( Callee & callee, void ( Callee::*func )( P1, P2, P3, P4, P5, P6 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  sq_argassert( 4, index + 3 );
  sq_argassert( 5, index + 4 );
  sq_argassert( 6, index + 5 );
  ( callee.*func )(
    Get( TypeWrapper<P1>(), v, index + 0 ),
    Get( TypeWrapper<P2>(), v, index + 1 ),
    Get( TypeWrapper<P3>(), v, index + 2 ),
    Get( TypeWrapper<P4>(), v, index + 3 ),
    Get( TypeWrapper<P5>(), v, index + 4 ),
    Get( TypeWrapper<P6>(), v, index + 5 )
  );
  return 0;
}

template<typename Callee, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
static int Call( Callee & callee, void ( Callee::*func )( P1, P2, P3, P4, P5, P6, P7 ) const, HSQUIRRELVM v, int index ) {
  sq_argassert( 1, index + 0 );
  sq_argassert( 2, index + 1 );
  sq_argassert( 3, index + 2 );
  sq_argassert( 4, index + 3 );
  sq_argassert( 5, index + 4 );
  sq_argassert( 6, index + 5 );
  sq_argassert( 7, index + 6 );
  ( callee.*func )(
    Get( TypeWrapper<P1>(), v, index + 0 ),
    Get( TypeWrapper<P2>(), v, index + 1 ),
    Get( TypeWrapper<P3>(), v, index + 2 ),
    Get( TypeWrapper<P4>(), v, index + 3 ),
    Get( TypeWrapper<P5>(), v, index + 4 ),
    Get( TypeWrapper<P6>(), v, index + 5 ),
    Get( TypeWrapper<P7>(), v, index + 6 )
  );
  return 0;
}
#endif

#ifdef SQPLUS_CALL_CONST_MFUNC_RET1
#undef SQ_REG_CONST_STATIC_VAR
template<typename Callee, typename RT>
int Call( Callee & callee, RT( Callee::*func )() const, HSQUIRRELVM v, int index ) {
  return ReturnSpecialization<RT>::Call( callee, func, v, index );
}

template<typename Callee, typename RT, typename P1>
int Call( Callee & callee, RT( Callee::*func )( P1 ) const, HSQUIRRELVM v, int index ) {
  return ReturnSpecialization<RT>::Call( callee, func, v, index );
}

template<typename Callee, typename RT, typename P1, typename P2>
int Call( Callee & callee, RT( Callee::*func )( P1, P2 ) const, HSQUIRRELVM v, int index ) {
  return ReturnSpecialization<RT>::Call( callee, func, v, index );
}

template<typename Callee, typename RT, typename P1, typename P2, typename P3>
int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3 ) const, HSQUIRRELVM v, int index ) {
  return ReturnSpecialization<RT>::Call( callee, func, v, index );
}

template<typename Callee, typename RT, typename P1, typename P2, typename P3, typename P4>
int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3, P4 ) const, HSQUIRRELVM v, int index ) {
  return ReturnSpecialization<RT>::Call( callee, func, v, index );
}

template<typename Callee, typename RT, typename P1, typename P2, typename P3, typename P4, typename P5>
int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3, P4, P5 ) const, HSQUIRRELVM v, int index ) {
  return ReturnSpecialization<RT>::Call( callee, func, v, index );
}

template<typename Callee, typename RT, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3, P4, P5, P6 ) const, HSQUIRRELVM v, int index ) {
  return ReturnSpecialization<RT>::Call( callee, func, v, index );
}

template<typename Callee, typename RT, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
int Call( Callee & callee, RT( Callee::*func )( P1, P2, P3, P4, P5, P6, P7 ) const, HSQUIRRELVM v, int index ) {
  return ReturnSpecialization<RT>::Call( callee, func, v, index );
}
#undef SQPLUS_CALL_CONST_MFUNC_RET1
#endif

#ifdef SQ_REG_CONST_STATIC_VAR
template<typename VarType>
SQClassDef & staticVar( const VarType * pvar, const SQChar * name_, VarAccessType access = VAR_ACCESS_READ_ONLY ) {
  struct CV {
    const VarType * var;
  } cv;
  cv.var = pvar;
  RegisterInstanceVariable( newClass, ClassType<TClassType>::type(), *( VarType ** )&cv, name_, VarAccessType( access | VAR_ACCESS_STATIC ) );
  return *this;
}
#endif
